package com.security;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName SessionFilter
 * @Description TODO 从session获取token,统一加到请求头中去
 * @Author wushaopei
 * @Date 2021/5/15 14:31
 * @Version 1.0
 */
@Component
@Slf4j
public class SessionFilter extends ZuulFilter {

  private RestTemplate restTemplate = new RestTemplate();

  @Override
  public String filterType() {
    return "pre";
  }

  @Override
  public int filterOrder() {
    return 0;
  }

  @Override
  public boolean shouldFilter() {
    return true;
  }

  @Override
  public Object run() throws ZuulException {

    RequestContext requestContext = RequestContext.getCurrentContext();
    HttpServletRequest request = requestContext.getRequest();

    TokenInfo token = (TokenInfo)request.getSession().getAttribute("token");

    if(token != null){
      // 获取access_token
      String tokenValue = token.getAccess_token();
      // 新增 refresh_token 刷新access_token令牌的逻辑
      if(token.isExpired()){
        //认证服务器验token地址 /oauth/check_token 是  spring .security.oauth2的验token端点
        String oauthServiceUrl = "http://gateway.imooc.com:9070/token/oauth/token";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 不是json请求
        // 网关的appId，appSecret，需要在数据库oauth_client_details注册
        headers.setBasicAuth("admin","123456");
        // 封装token
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("refresh_token",token.getRefresh_token()); // 刷新令牌
        params.add("grant_type","refresh_token"); //授权类型-刷新令牌模式

        HttpEntity<MultiValueMap<String,String>> entity = new HttpEntity<>(params,headers);

        try{
          ResponseEntity<TokenInfo> newToken = restTemplate.exchange(oauthServiceUrl, HttpMethod.POST,entity,TokenInfo.class);
          request.getSession().setAttribute("token",newToken.getBody().init());
          log.info("刷新令牌： {}", newToken.getBody());
          tokenValue  = newToken.getBody().getAccess_token();
        }catch (Exception e){
          requestContext.setSendZuulResponse(false);
          requestContext.setResponseStatusCode(500);
          requestContext.setResponseBody("{\"message\":\"refresh fail\"}");
          requestContext.getResponse().setContentType("application/json");
        }

      }
      requestContext.addZuulRequestHeader("Authorization","bearer " + token.getAccess_token());
    }
    return null;
  }
}
